package cn.sq.scaffold.ffmpeg.utils;

import cn.sq.scaffold.ffmpeg.exception.FileChangeExeception;
import cn.sq.scaffold.ffmpeg.hander.FfmpegHander;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.omg.CORBA.SystemException;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: SQ
 * Date: 2020/11/17
 * Time: 16:49
 * Description:
 */
@Slf4j
public class CmdUtils {
    // 日志
//    private static final Logger LOG = LoggerFactory.getLogger(CmdUtils.class);
    /**
     * 执行命令(同步)
     *
     * @param command
     *            命令
     * @throws SystemException
     */
    public boolean exe(List<String> command) throws SystemException {
        Process process=null;
        BufferedReader reader = null;
        try {
             process = Runtime.getRuntime().exec(command.toArray(new String[command.size()]));
            // 以下代码为控制台输出相关的批出理
            String line = null;
            reader = new BufferedReader(new InputStreamReader(
                    process.getInputStream(), "UTF-8"));
            while ((line = reader.readLine()) != null) {
                log.info(line);
            }

            // 等待刚刚执行的命令的结束
            while (true) {
                if (process.waitFor() == 0) {
                    break;
                }
            }
        } catch (Exception e) {
//            throw new SystemException("执行cmd命令时发生异常,异常信息:"+e.getMessage(),0);
            log.error("执行cmd命令时发生异常,异常信息:"+e.getMessage());
        } finally {
            process.destroy();
            try {
                reader.close();
                return true;
            } catch (IOException e) {
                log.error("exe:", e);
                return false;
            }
        }
    }
    /**
     * 执行命令(异步)
     * @param command
     * @return boolean
     */
    public static boolean process(List<String> command) {
        try {
            log.debug(ListUtils.convertToString(command, " "));
//			Process process = new ProcessBuilder(command).redirectErrorStream(true).start();
            Process process = Runtime.getRuntime().exec(command.toArray(new String[command.size()]));
            new PrintErrorReader(process.getErrorStream()).start();
            new PrintInputStream(process.getInputStream()).start();
            process.waitFor();
            return true;
        } catch (Exception e) {
            if (org.apache.commons.lang3.StringUtils.contains(e.getMessage(), "CreateProcess error=2")){
                log.error("缺少视频转换工具，请配置video.ffmpegFile相关参数。" + e.getMessage());
            }else{
                log.error(e.getMessage(), e);
            }
            return false;
        }
    }
    static class PrintInputStream extends Thread {
        java.io.InputStream __is = null;

        public PrintInputStream(java.io.InputStream is) {
            __is = is;
        }

        @Override
        public void run() {
            try {
                BufferedReader br = new BufferedReader(new InputStreamReader(__is));
                String line = null;
                while ((line = br.readLine()) != null) {
                    log.debug(line);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    static class PrintErrorReader extends Thread {
        java.io.InputStream __is = null;

        public PrintErrorReader(java.io.InputStream is) {
            __is = is;
        }

        @Override
        public void run() {
            try {
                BufferedReader br = new BufferedReader(new InputStreamReader(__is));
                String line = null;
                while ((line = br.readLine()) != null) {
                    log.info(line);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 检查文件名格式
     * @return
     */
    public static boolean checkContentType(String filename) {
        // ffmpeg 能解析的格式：（asx，asf，mpg，wmv，3gp，mp4，mov，avi，flv，rm，rmvb等）
        if (inStringIgnoreCase(filename, ".avi", ".mpg", ".wmv", ".3gp", ".mov",
                ".mp4", ".asf", ".asx", ".flv", ".rm", ".rmvb")) {
            return true;
        }
        return false;
    }
    /**
     * 是否包含字符串
     * @param str 验证字符串
     * @param strs 字符串组
     * @return 包含返回true
     */
    public static boolean inStringIgnoreCase(String str, String... strs){
        if (str != null && strs != null){
            for (String s : strs){
                if (str.equalsIgnoreCase(org.apache.commons.lang3.StringUtils.trim(s))){
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 是否包含字符串
     * @param str 验证字符串
     * @param strs 字符串组
     * @return 包含返回true
     */
    public static boolean inString(String str, String... strs){
        if (str != null && strs != null){
            for (String s : strs){
                if (str.equals(org.apache.commons.lang3.StringUtils.trim(s))){
                    return true;
                }
            }
        }
        return false;
    }
    /**
     * 获取指定文件或文件夹的后缀名
     * @param fileName  文件名称
     * @return
     */
    public static String getFileSuffix(String fileName){
        return fileName.substring(fileName.lastIndexOf("."));//例如：abc.png  截取后：.png
    }
    /**
     * 获取指定文件或文件夹的后缀名
     * @param file  文件名称
     * @return
     */
    public static String getFileSuffix(File file){
        String name = file.getName();
        return name.substring(name.lastIndexOf("."));//例如：abc.png  截取后：.png
    }

    /**
     * 检查指定文件是否符合视频格式规定
     * @param file  文件名称
     * @return
     */
    public static boolean checkFileType(File file){
        return CmdUtils.inStringIgnoreCase(CmdUtils.getFileSuffix(file.getName()));
    }

    /**
     *  multipartFile转File
     * @param multipartFile spring 文件流
     * @param outfilepath 生成文件地址
     * @return 是否成功
     * @throws IOException
     */
    public static boolean multipartFileToFile(MultipartFile multipartFile,String outfilepath) throws FileChangeExeception {
        try {
            File file = new File(outfilepath);
            boolean isCreateSuccess = file.createNewFile();
            if(isCreateSuccess){
                FileUtils.copyInputStreamToFile(multipartFile.getInputStream(), file);
            }
        } catch (IOException e) {
            e.printStackTrace();
            log.error(e.getMessage());
            throw new FileChangeExeception("multipartFile转File异常");
        }
        return true;
    }

    public static void download(String filename, HttpServletResponse res) throws IOException {
        // 发送给客户端的数据
        OutputStream outputStream = res.getOutputStream();
        byte[] buff = new byte[1024];
        BufferedInputStream bis = null;
        // 读取filename
        bis = new BufferedInputStream(new FileInputStream(new File(filename)));
        int i = bis.read(buff);
        while (i != -1) {
            outputStream.write(buff, 0, buff.length);
            outputStream.flush();
            i = bis.read(buff);
        }
    }




}
